package mp

import (
	"duoke/internal/dao"
	"duoke/internal/model/entity"
	"duoke/model"
	"duoke/service"
	yogaService "duoke/service/yoga"
	"duoke/tables"
	"duoke/utils/gconv"
	"duoke/utils/gjson"
	"duoke/utils/gtime"
	"duoke/utils/orm"
	"duoke/utils/response/tencent_im"
	"duoke/utils/wechat_v3"
	"duoke/utils/yaml"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/wechat"
	wechat3 "github.com/go-pay/gopay/wechat/v3"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/sirupsen/logrus"
	"net/http"
	"time"
)

var Notify = new(notifyCtl)

type notifyCtl struct{}

func (ctl *notifyCtl) Wxpay(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	logrus.Info("团员支付：", notifyReq)
	// 查找订单
	order := new(model.Order)
	orderNo := notifyReq.GetString("out_trade_no")
	has, _ := orm.Db.Where("order_no =? AND pay_state = ?", orderNo, 0).Get(order)
	if !has {
		logrus.Error("支付订单不存在，订单号：" + orderNo)
		return
	}
	c.Set("account", service.AccountStruct{Id: order.Acid})
	// 查询商品
	goods := new(model.ReqGoods)
	has, err = orm.Db.Where("id =?", order.GoodsId).Get(goods)
	if !has {
		logrus.Error("支付商品不存在，订单号：" + orderNo)
		return
	}
	c.Set("goods", goods)
	// 获取用户
	user := new(tables.GoodsUser)
	has, _ = orm.Db.Where("user_id =? AND goods_id =?", order.UserId, goods.Id).Get(user)
	if !has {
		logrus.Error("订单用户不存在，订单号：" + orderNo)
		return
	}
	// 获取平台
	platform, err := service.AccountSetting.Info(c, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置，订单号："+orderNo, err.Error())
		return
	}
	if platform == nil {
		logrus.Error("小程序配置信息不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["app_id"]) == "" {
		logrus.Error("小程序appid不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["pay_mch_id"]) == "" {
		logrus.Error("微信支付商户ID不存在："+orderNo, err.Error())
		return
	}
	// 验签操作
	//ok, _ := wechat.VerifySign(gconv.String(platform["pay_key"]), wechat.SignType_MD5, notifyReq)
	//if !ok {
	//	logrus.Error("支付回调验签失败，订单号：" + orderNo)
	//	return
	//}
	// 更新订单数据
	order.PayState = 1
	order.PayTime = gconv.Int(time.Now().Unix())
	affected, _ := orm.Db.ID(order.Id).Cols("pay_state", "pay_time").Update(order)
	if affected == 0 {
		logrus.Error("订单状态更新失败，订单号：" + orderNo)
		return
	}
	// 增加商品销量、收入、减库存
	goods.Sales = goods.Sales + 1
	goods.Income = goods.Income + order.PayAmount
	goods.Stock = goods.Stock - 1
	_, _ = orm.Db.ID(order.GoodsId).Cols("sales", "income", "stock").Update(goods)
	// 更新团订单 获取团长订单
	headOrder := new(model.Order)
	if order.GroupId > 0 {
		_, _ = orm.Db.ID(order.GroupId).Get(headOrder)
	}
	// 赠送积分
	scoreSetting, err := service.AccountSetting.Info(c, "score")
	if err == nil {
		service.User.Score(c, order.UserId, gconv.Int(gconv.Float64(order.PayAmount)*gconv.Float64(scoreSetting["money_to_score_rate"])), "拼团成功赠送积分")
	}
	if headOrder.Id > 0 {
		// 团成员数量 +1，并判断是否满团
		groupMemberNum, _ := orm.Db.Where("group_id =? AND pay_state = 1 AND refund_state = 0", order.GroupId).Count(new(model.Order))
		orderUpdate := new(model.Order)
		if groupMemberNum > 0 {
			orderUpdate.GroupMemberNum = gconv.Int(groupMemberNum)
		} else {
			orderUpdate.GroupMemberNum = headOrder.GroupMemberNum + 1
		}
		if headOrder.GroupNum <= orderUpdate.GroupMemberNum {
			orderUpdate.GroupState = 1
		} else {
			orderUpdate.GroupState = 0
		}
		if headOrder.GroupNum < orderUpdate.GroupMemberNum {
			orderUpdate.GroupNum = orderUpdate.GroupMemberNum
		} else {
			orderUpdate.GroupNum = headOrder.GroupNum
		}
		// 满员退押金

		if orderUpdate.GroupState == 1 {
			// 先查出团长
			// 成团返佣
			if goods.FullReturn == 1 {
				err = service.User.UserMoney(c, headOrder.UserId, float64(headOrder.PayAmount), "成团奖励", "")
				if err != nil {
					logrus.Error("成团失败，订单号："+orderNo, err.Error())
					return
				}
			}
			// 判断是否已经插入成功开团表 如果有权重加1 没有则新建
			var gp tables.GroupOpen
			get, err := orm.Db.Where("goods_id=? and user_id=?", headOrder.GoodsId, headOrder.UserId).Get(&gp)
			if err != nil {
				logrus.Error("获取成团数据失败，订单号："+orderNo, err.Error())
				return
			}
			// 判断是否已经插入成功开团表 如果有权重加1 没有则新建
			if get {
				gp.Weight += 1
				gp.GroupCount += 1
				orm.Db.Where("goods_id=?", gp.Id).Update(gp)
			} else {
				gp = tables.GroupOpen{
					GoodsId:    headOrder.GoodsId,
					UserId:     headOrder.UserId,
					Weight:     1,
					Nickname:   headOrder.Nickname,
					Avatar:     headOrder.Avatar,
					GroupCount: 1,
					GoodsPhoto: headOrder.GoodsPhoto,
					GoodsTitle: headOrder.GoodsTitle,
					SubMchId:   service.User.GetValueById(headOrder.UserId, "sub_mch_id"),
				}
				orm.Db.Insert(gp)
			}
			m := map[string]any{
				"headOrder":     headOrder,
				"group_points":  goods.GroupPoints,
				"member_points": goods.MemberPoints,
			}
			// 赠送积分
			err = service.Group.GiveIntegral(c, m)
			if err != nil {
				logrus.Error("赠送积分失败，订单号："+orderNo, err.Error())
			}
			// 赠送卡密
			err = service.UserCarmine.GiveCarmine(c, goods.CarmineId, goods.CarmineNumber, headOrder.UserId)
			if err != nil {
				logrus.Error("赠送卡密失败，订单号："+orderNo, err.Error())
			}
			fmt.Println(err)
		}
		_, _ = orm.Db.Where("pay_state = 1 AND refund_state = 0 AND group_id =?", order.GroupId).Cols("group_num", "group_member_num", "group_state").Update(orderUpdate)
	}
	// 是否赠送卡券
	if gconv.Int(goods.Config["give_coupon_id"]) > 0 {
		service.Coupon.Give(c, gconv.Int(goods.Config["give_coupon_id"]), order.UserId, order.Name, order.Phone, gconv.Int(order.FromId))
	}
	// 发放奖励
	if order.FromId > 0 && gconv.Float64(goods.Sp1Reward) > 0 {
		remark := "来自" + user.Nickname + "一级奖励"
		service.User.UserMoney(c, order.FromId, gconv.Float64(goods.Sp1Reward), remark, "user_spread_reward")
		//_, err = service.Reward.Send(c, 1, order.Acid, goods.Id, goods.Title, order.FromId, gconv.Float64(goods.Sp1Reward), orderNo, order.UserId, remark, goods.SpRewardAutoSend == 1)
		//if err != nil {
		//	logrus.Error("奖励发放失败-1，订单号："+orderNo, err.Error())
		//}
	}
	if order.FromId2 > 0 && gconv.Float64(goods.Sp2Reward) > 0 {
		remark := "来自" + user.Nickname + "二级奖励"
		service.User.UserMoney(c, order.FromId2, gconv.Float64(goods.Sp2Reward), remark, "user_spread_reward")
		//_, err = service.Reward.Send(c, 1, order.Acid, goods.Id, goods.Title, order.FromId2, gconv.Float64(goods.Sp2Reward), orderNo, order.UserId, remark, goods.SpRewardAutoSend == 1)
		//if err != nil {
		//	logrus.Error("奖励发放失败-2，订单号："+orderNo, err.Error())
		//}
	}
	// ==异步通知，返回给微信平台的信息==
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}

// 商户卡券支付回调
func (ctl *notifyCtl) MerchantCouponPay(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo := notifyReq.GetString("out_trade_no")
	c.Set("account", service.AccountStruct{Id: 1})
	// 获取平台
	platform, err := service.AccountSetting.Info(c, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置，订单号："+orderNo, err.Error())
		return
	}
	if platform == nil {
		logrus.Error("小程序配置信息不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["app_id"]) == "" {
		logrus.Error("小程序appid不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["pay_mch_id"]) == "" {
		logrus.Error("微信支付商户ID不存在："+orderNo, err.Error())
		return
	}
	// 验签操作
	ok, _ := wechat.VerifySign(gconv.String(platform["pay_key"]), wechat.SignType_MD5, notifyReq)
	if !ok {
		logrus.Error("支付回调验签失败，订单号：" + orderNo)
		return
	}
	// 卡券
	var coupon *entity.Coupon
	err = dao.Coupon.Ctx(c).Where("order_no", orderNo).Where("status", 0).Scan(&coupon)
	if err != nil || coupon.Id == 0 {
		logrus.Error("卡券订单不存在" + orderNo)
		return
	}
	// 更新订单数据
	update, err := dao.Coupon.Ctx(c).Data(g.Map{"status": 1, "pay_time": gtime.TimeStamp()}).Where("order_no", orderNo).Where("status", 0).Update()
	if row, err := update.RowsAffected(); err != nil || row == 0 {
		logrus.Error("卡券订单状态更新失败" + orderNo)
		return
	}
	// ==异步通知，返回给微信平台的信息==
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}

// 用户卡券支付回调
func (ctl *notifyCtl) UserCouponPay(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	logrus.Info("支付回调数据", notifyReq)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo := notifyReq.GetString("out_trade_no")
	c.Set("account", service.AccountStruct{Id: 1})
	// 获取平台
	platform, err := service.AccountSetting.Info(c, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置，订单号："+orderNo, err.Error())
		return
	}
	if platform == nil {
		logrus.Error("小程序配置信息不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["app_id"]) == "" {
		logrus.Error("小程序appid不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["pay_mch_id"]) == "" {
		logrus.Error("微信支付商户ID不存在："+orderNo, err.Error())
		return
	}
	// 验签操作
	ok, _ := wechat.VerifySign(gconv.String(platform["pay_key"]), wechat.SignType_MD5, notifyReq)
	if !ok {
		logrus.Error("支付回调验签失败，订单号：" + orderNo)
		return
	}
	// 订单
	var couponOrder *entity.CouponOrder
	err = dao.CouponOrder.Ctx(c).Where("order_no", orderNo).Where("pay_status", 0).Scan(&couponOrder)
	if err != nil || couponOrder == nil {
		logrus.Error("卡券订单不存在" + orderNo)
		return
	}
	// 卡券
	var coupon *entity.Coupon
	err = dao.Coupon.Ctx(c).Where("id", couponOrder.CouponId).Scan(&coupon)
	if err != nil || coupon.Id == 0 {
		logrus.Error("卡券订单不存在" + orderNo)
		return
	}
	// 用户
	var user *entity.User
	err = dao.User.Ctx(c).Where("id", couponOrder.UserId).Scan(&user)
	if err != nil || user.Id == 0 {
		logrus.Error("用户不存在" + orderNo)
		return
	}
	// 更新订单数据
	update, err := dao.CouponOrder.Ctx(c).
		Data(g.Map{"pay_status": 1, "pay_time": gtime.TimeStamp(), "transaction_id": notifyReq.GetString("transaction_id")}).
		Where("id", couponOrder.Id).Update()
	if row, err := update.RowsAffected(); err != nil || row == 0 {
		logrus.Error("卡券订单状态更新失败" + orderNo)
		return
	}

	// 赠送积分
	scoreSetting, err := service.AccountSetting.Info(c, "score")
	if err == nil {
		service.User.Score(c, couponOrder.UserId, gconv.Int(gconv.Float64(couponOrder.PayAmount/100)*gconv.Float64(scoreSetting["money_to_score_rate"])), "购买卡券赠送积分")
	}
	// 减少库存
	update2, err := dao.Coupon.Ctx(c).Where("id", couponOrder.CouponId).Decrement("stock", 1)
	if row, err := update2.RowsAffected(); err != nil || row == 0 {
		logrus.Error("卡券库存更新失败" + orderNo)
		return
	}
	// 增加销量
	update3, err := dao.Coupon.Ctx(c).Where("id", couponOrder.CouponId).Increment("sales", 1)
	if row, err := update3.RowsAffected(); err != nil || row == 0 {
		logrus.Error("卡券销量更新失败" + orderNo)
		return
	}
	// 推广奖励
	var rewardAmount float64
	if couponOrder.Fid > 0 && coupon.FidReward > 0 {
		rewardAmount = coupon.FidReward
		var fUser *entity.User
		err = dao.User.Ctx(c).Where("id", couponOrder.Fid).Scan(&fUser)
		if err != nil || fUser.Id == 0 {
			logrus.Error("推广用户不存在，无法奖励" + orderNo)
		}
		remark := "来自" + user.Nickname + "奖励"
		service.User.UserMoney(c, couponOrder.Fid, coupon.FidReward, remark, "user_money")
	}
	// 添加分账逻辑
	err = service.User.UserMoney(c, coupon.UserId, gconv.Float64(couponOrder.PayAmount/100)-rewardAmount, "用户购买卡券到账，分销扣除金额"+gconv.String(rewardAmount)+"元", "merchant_coupon_sale")
	if err != nil {
		logrus.Error("用户购买卡券到账失败" + orderNo)
	}
	config := yaml.GetConfig()
	if config.SubMch.SubType != "2" {
		// TOODO分账逻辑
		go func() {
			time.Sleep(3 * time.Second)
			err = service.SeparateAccounts.SeparateAccountsV2(c, notifyReq)
			if err != nil {
				_, err = dao.CouponOrder.Ctx(c).
					Data(g.Map{"separate_state": 2}).Where("order_no", orderNo).Unscoped().Update()
				logrus.Error("分账逻辑错误：UserCouponPay:" + err.Error())
				return
			}
			_, err = dao.CouponOrder.Ctx(c).Data(g.Map{"separate_state": 1}).
				Where("order_no", orderNo).Unscoped().Update()
		}()
	}

	// ==异步通知，返回给微信平台的信息==
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}

// 商户充值支付回调
func (ctl *notifyCtl) UserRechargePay(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo := notifyReq.GetString("out_trade_no")
	c.Set("account", service.AccountStruct{Id: 1})
	// 获取平台
	platform, err := service.AccountSetting.Info(c, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置，订单号："+orderNo, err.Error())
		return
	}
	if platform == nil {
		logrus.Error("小程序配置信息不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["app_id"]) == "" {
		logrus.Error("小程序appid不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["pay_mch_id"]) == "" {
		logrus.Error("微信支付商户ID不存在："+orderNo, err.Error())
		return
	}
	// 验签操作
	ok, _ := wechat.VerifySign(gconv.String(platform["pay_key"]), wechat.SignType_MD5, notifyReq)
	if !ok {
		logrus.Error("支付回调验签失败，订单号：" + orderNo)
		return
	}
	var userRechargeOrder *entity.UserMoneyLog
	err = dao.UserMoneyLog.Ctx(c).Where("order_no", orderNo).Where("status", 0).Scan(&userRechargeOrder)
	if err != nil || userRechargeOrder == nil {
		logrus.Error("充值订单不存在" + orderNo)
		return
	}
	// 更新订单数据
	update, err := dao.UserMoneyLog.Ctx(c).Data(g.Map{"status": 1, "pay_time": gtime.TimeStamp()}).Where("id", userRechargeOrder.Id).Unscoped().Update()
	if row, err := update.RowsAffected(); err != nil || row == 0 {
		logrus.Error("充值订单状态更新失败"+orderNo, err.Error())
		return
	}
	// 增加余额
	//update3, err := dao.User.Ctx(c).Where("id", userRechargeOrder.UserId).Unscoped().Increment("money", userRechargeOrder.Amount)
	//if row, err := update3.RowsAffected(); err != nil || row == 0 {
	//	logrus.Error("余额增加更新失败" + orderNo)
	//	return
	//}
	// 商户余额增加
	err = service.Merchant.Money(c, userRechargeOrder.UserId, userRechargeOrder.Amount, "商户充值到账")
	if err != nil {
		logrus.Error("商户充值到账失败" + orderNo)
	}
	// ==异步通知，返回给微信平台的信息==
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}

// CourseNotify 微信视频支付回调
func (ctl *notifyCtl) CourseNotify(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	logrus.Info("支付回调数据", notifyReq)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo := notifyReq.GetString("out_trade_no")
	c.Set("account", service.AccountStruct{Id: 1})
	// 获取平台
	platform, err := service.AccountSetting.Info(c, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置，订单号："+orderNo, err.Error())
		return
	}
	if platform == nil {
		logrus.Error("小程序配置信息不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["app_id"]) == "" {
		logrus.Error("小程序appid不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["pay_mch_id"]) == "" {
		logrus.Error("微信支付商户ID不存在："+orderNo, err.Error())
		return
	}
	// 验签操作
	ok, _ := wechat.VerifySign(gconv.String(platform["pay_key"]), wechat.SignType_MD5, notifyReq)
	if !ok {
		logrus.Error("支付回调验签失败，订单号：" + orderNo)
		return
	}
	// 未支付订单
	var co *entity.CourseOrder
	err = dao.CourseOrder.Ctx(c).Where("order_no", orderNo).Where("state", 2).Scan(&co)
	if err != nil || co == nil {
		logrus.Error("视频订单不存在" + orderNo)
		return
	}
	var list_id int
	if co.Type == 1 {
		one, err := dao.CourseList.Ctx(c).Where("id", co.VideoId).One()
		if err != nil || one.IsEmpty() {
			logrus.Error("视频栏目订单不存在" + orderNo)
			return
		}
		list_id = co.VideoId
	} else {
		one, err := dao.CourseVideo.Ctx(c).Where("id", co.VideoId).One()
		if err != nil || one.IsEmpty() {
			logrus.Error("视频栏目订单不存在" + orderNo)
			return
		}
		var cv entity.CourseVideo
		err = one.Struct(&cv)
		if err != nil || one.IsEmpty() {
			logrus.Error(err.Error() + orderNo)
			return
		}
		list_id = cv.ListId
	}
	// 用户
	var user *entity.User
	err = dao.User.Ctx(c).Where("id", co.UserId).Scan(&user)
	if err != nil || user.Id == 0 {
		logrus.Error("用户不存在" + orderNo)
		return
	}
	// 更新订单数据
	update, err := dao.CourseOrder.Ctx(c).
		Data(g.Map{"state": 1, "pay_time": gtime.TimeStamp(), "is_effective": 3,
			"transaction_id": notifyReq.GetString("transaction_id")}).
		Where("id", co.Id).Update()
	if row, err := update.RowsAffected(); err != nil || row == 0 {
		logrus.Error("卡券订单状态更新失败" + orderNo)
		return
	}
	// 增加销量
	update3, err := dao.CourseList.Ctx(c).Where("id", list_id).Increment("buy", 1)
	if row, err := update3.RowsAffected(); err != nil || row == 0 {
		logrus.Error("购买数增加失败" + orderNo)
		return
	}
	config := yaml.GetConfig()
	if config.SubMch.SubType != "2" {
		// TOODO分账逻辑
		go func() {
			// 先绑定用户
			err = service.SeparateAccounts.BindUser(c, &model.ReqSubAccount{
				SubMchId:         gconv.String(notifyReq["sub_mch_id"]),
				ReceivierType:    "PERSONAL_OPENID",
				ReceivierAccount: gconv.String(notifyReq["sub_openid"]),
			})
			if err != nil {
				logrus.Error("支付订单用户绑定失败，订单号：" + orderNo)
				return
			}
			time.Sleep(3 * time.Second)
			err = service.SeparateAccounts.SeparateAccountsV2(c, notifyReq)
			if err != nil {
				// 这里修改状态为2 分账失败
				_, err = dao.CourseOrder.Ctx(c).Data(g.Map{"separate_state": 2}).
					Where("order_no", orderNo).Unscoped().Update()
				logrus.Error("分账逻辑错误：CourseNotify:" + err.Error())
				return
			}
			//这里修改状态为1 分账成功
			_, err = dao.CourseOrder.Ctx(c).Data(g.Map{"separate_state": 1}).
				Where("order_no", orderNo).Unscoped().Update()
		}()
	}
	// ==异步通知，返回给微信平台的信息==
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}

func (ctl *notifyCtl) TencentApi(c *gin.Context) {
	//json := request.JsonMap(c)
	//switch gconv.String(json["CallbackCommand"]) {
	//case "C2C.CallbackBeforeSendMsg":
	//	var req model.CallbackBeforeSendMsgReq
	//	if err := c.ShouldBind(&req); err != nil {
	//		response.Error(c, err.Error(), nil)
	//		return
	//	}
	//	service.TencentIm.CallbackBeforeSendMsg(&req)
	//	tencent_im.Success(c, "success", nil)
	//}
	var msg [1]model.MsgContent
	msg[0].MsgType = "TIMTextElem"
	msg[0].MsgContent.Text = "zio3"
	tencent_im.Success(c, 0, "ok", msg)
}
func (ctl *notifyCtl) SeparateNotify(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	logrus.Info("商户支付回调", notifyReq)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo := notifyReq.GetString("out_trade_no")
	c.Set("account", service.AccountStruct{Id: 1})
	// 获取平台
	platform, err := service.AccountSetting.Info(c, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置，订单号："+orderNo, err.Error())
		return
	}
	if platform == nil {
		logrus.Error("小程序配置信息不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["app_id"]) == "" {
		logrus.Error("小程序appid不存在："+orderNo, err.Error())
		return
	}
	if gconv.String(platform["pay_mch_id"]) == "" {
		logrus.Error("微信支付商户ID不存在："+orderNo, err.Error())
		return
	}
	// 验签操作
	ok, _ := wechat.VerifySign(gconv.String(platform["pay_key"]), wechat.SignType_MD5, notifyReq)
	if !ok {
		logrus.Error("支付回调验签失败，订单号：" + orderNo)
		return
	}
	var co *entity.SepatateOrder
	err = dao.SepatateOrder.Ctx(c).Where("order_no", orderNo).Where("state", 2).Scan(&co)
	if err != nil || co == nil {
		logrus.Error("商户订单不存在" + orderNo)
		return
	}

	// 更新订单数据
	update, err := dao.SepatateOrder.Ctx(c).
		Data(g.Map{"state": 1, "pay_time": gtime.TimeStamp(),
			"transaction_id": notifyReq.GetString("transaction_id")}).
		Where("order_no", orderNo).Update()
	if row, err := update.RowsAffected(); err != nil || row == 0 {
		logrus.Error("订单支付更新状态失败" + orderNo)
		return
	}
	config := yaml.GetConfig()
	if config.SubMch.SubType != "2" {
		// 先绑定用户
		err = service.SeparateAccounts.BindUser(c, &model.ReqSubAccount{
			SubMchId:         gconv.String(notifyReq["sub_mch_id"]),
			ReceivierType:    "PERSONAL_OPENID",
			ReceivierAccount: gconv.String(notifyReq["sub_openid"]),
		})
		if err != nil {
			logrus.Error("支付订单用户绑定失败，订单号：" + orderNo)
			return
		}
		// 未支付订单
		time.Sleep(2 * time.Second)
		err = service.SeparateAccounts.SeparateAccountsV2(c, notifyReq)
		if err != nil {
			// 这里修改状态为2 分账失败
			_, err = dao.SepatateOrder.Ctx(c).Data(g.Map{"separate_state": 2}).
				Where("order_no", orderNo).Unscoped().Update()
			logrus.Error("分账逻辑错误：SeparateOrder:" + err.Error())
			return
		}
		//这里修改状态为1 分账成功
		_, err = dao.SepatateOrder.Ctx(c).Data(g.Map{"separate_state": 1}).
			Where("order_no", orderNo).Unscoped().Update()
	}
	// ==异步通知，返回给微信平台的信息==
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}

func (ctl *notifyCtl) ShortNotify(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	logrus.Info("短视频回调", notifyReq)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo, done := ctl.checkOrder(c, notifyReq, err)
	if done {
		return
	}
	var co *entity.ShortOrder
	err = dao.ShortOrder.Ctx(c).Where("order_no", orderNo).Where("state", 1).Scan(&co)
	if err != nil || co == nil {
		logrus.Error("商户订单不存在" + orderNo)
		return
	}

	// 更新订单数据
	update, err := dao.ShortOrder.Ctx(c).
		Data(g.Map{"state": 1, "pay_time": gtime.TimeStamp(),
			"transaction_id": notifyReq.GetString("transaction_id")}).
		Where("order_no", orderNo).Update()
	if row, err := update.RowsAffected(); err != nil || row == 0 {
		logrus.Error("订单支付更新状态失败" + orderNo)
		return
	}
	config := yaml.GetConfig()
	if config.SubMch.SubType != "2" {
		// 先绑定用户
		err = service.SeparateAccounts.BindUser(c, &model.ReqSubAccount{
			SubMchId:         gconv.String(notifyReq["sub_mch_id"]),
			ReceivierType:    "PERSONAL_OPENID",
			ReceivierAccount: gconv.String(notifyReq["sub_openid"]),
		})
		if err != nil {
			logrus.Error("支付订单用户绑定失败，订单号：" + orderNo)
			return
		}

		// 未支付订单
		time.Sleep(2 * time.Second)
		err = service.SeparateAccounts.SeparateAccountsV2(c, notifyReq)
		if err != nil {
			// 这里修改状态为2 分账失败
			_, err = dao.ShortOrder.Ctx(c).Data(g.Map{"separate_state": 2}).
				Where("order_no", orderNo).Unscoped().Update()
			logrus.Error("分账逻辑错误：SeparateOrder:" + err.Error())
			return
		}
		//这里修改状态为1 分账成功
		_, err = dao.ShortOrder.Ctx(c).Data(g.Map{"separate_state": 1}).
			Where("order_no", orderNo).Unscoped().Update()
	}
	// ==异步通知，返回给微信平台的信息==
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}

func (ctl *notifyCtl) checkOrder(c *gin.Context, notifyReq gopay.BodyMap, err error) (string, bool) {
	orderNo := notifyReq.GetString("out_trade_no")
	c.Set("account", service.AccountStruct{Id: 1})
	// 获取平台
	platform, err := service.AccountSetting.Info(c, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置，订单号："+orderNo, err.Error())
		return "", true
	}
	if platform == nil {
		logrus.Error("小程序配置信息不存在："+orderNo, err.Error())
		return "", true
	}
	if gconv.String(platform["app_id"]) == "" {
		logrus.Error("小程序appid不存在："+orderNo, err.Error())
		return "", true
	}
	if gconv.String(platform["pay_mch_id"]) == "" {
		logrus.Error("微信支付商户ID不存在："+orderNo, err.Error())
		return "", true
	}
	// 验签操作
	ok, _ := wechat.VerifySign(gconv.String(platform["pay_key"]), wechat.SignType_MD5, notifyReq)
	if !ok {
		logrus.Error("支付回调验签失败，订单号：" + orderNo)
		return "", true
	}
	return orderNo, false
}
func (ctl *notifyCtl) YogaNotify(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	logrus.Info("瑜伽支付回调", notifyReq)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo, done := ctl.checkOrder(c, notifyReq, err)
	if done {
		return
	}
	err = yogaService.Order.YogaNotify(c, notifyReq)
	if err != nil {
		logrus.Error("支付订单用户绑定失败，订单号：" + orderNo + ";错误原因：" + err.Error())
		return
	}
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}
func (ctl *notifyCtl) YogaCourseNotify(c *gin.Context) {
	notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
	logrus.Info("瑜伽支付回调", notifyReq)
	if err != nil {
		logrus.Error("支付回调数据解析失败", err.Error())
		return
	}
	orderNo, done := ctl.checkOrder(c, notifyReq, err)
	if done {
		return
	}
	err = yogaService.Order.YogaCourseNotify(c, notifyReq)
	if err != nil {
		logrus.Error("支付订单用户绑定失败，订单号：" + orderNo + ";错误原因：" + err.Error())
		return
	}
	rsp := new(wechat.NotifyResponse) // 回复微信的数据
	rsp.ReturnCode = gopay.SUCCESS
	rsp.ReturnMsg = gopay.OK
	c.String(http.StatusOK, "%s", rsp.ToXmlString())
}
func (ctl *notifyCtl) Withdrawal(c *gin.Context) {
	res, err := service.AccountSetting.InfoById(1, "miniprogram")
	if err != nil {
		logrus.Error("小程序未设置")
		return
	}
	notify, err := wechat_v3.NewConfig(res).CheckTransferBillsNotify(c)
	logrus.Info("提现回调", notify)
	if notify.State == "SUCCESS" {
		info, err := service.Withdrawal.WithdrawalLogInfo(c, &model.SearchWithdrawal{OutBillNo: notify.OutBillNo})
		if err != nil {
			logrus.Error(err)
			return
		}
		err = service.Withdrawal.Update(c, &model.SearchWithdrawal{WithdrawalId: info.WithdrawalId, State: 5})
		if err != nil {
			logrus.Error(err)
			return
		}
	}
	c.JSON(http.StatusOK, &wechat3.V3NotifyRsp{Code: gopay.SUCCESS, Message: "成功"})
}

func (ctl *notifyCtl) Poll(c *gin.Context) {
	var req model.NotifyFastMailReq
	if err := c.ShouldBind(&req); err != nil {
		logrus.Info("快递100回调3-1:", gjson.StructOrMap2Json(req))
		c.JSON(http.StatusOK, gin.H{
			"result":     true,
			"returnCode": "500",
			"message":    "失败" + err.Error(),
		})
		return
	}
	logrus.Info("快递100回调3:", gjson.StructOrMap2Json(req))
	err := service.FastMail.Notify(c, &req.Param)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"result":     true,
			"returnCode": "500",
			"message":    "快递100回调" + err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"result":     true,
		"returnCode": "200",
		"message":    "成功",
	})
	return
}
